package com.leecode;

import java.util.*;

/**
 * 347. 前 K 个高频元素
 * <p>
 * 给定一个非空的整数数组，返回其中出现频率前 k 高的元素。
 * <p>
 * <p>
 * <p>
 * 示例 1:
 * <p>
 * 输入: nums = [1,1,1,2,2,3], k = 2
 * 输出: [1,2]
 * <p>
 * 示例 2:
 * <p>
 * 输入: nums = [1], k = 1
 * 输出: [1]
 * <p>
 * <p>
 * <p>
 * 提示：
 * <p>
 * 你可以假设给定的 k 总是合理的，且 1 ≤ k ≤ 数组中不相同的元素的个数。
 * 你的算法的时间复杂度必须优于 O(n log n) , n 是数组的大小。
 * 题目数据保证答案唯一，换句话说，数组中前 k 个高频元素的集合是唯一的。
 * 你可以按任意顺序返回答案。
 */
public class Leet347 {
	public static void main(String[] args) {
//		new Leet347().topKFrequent(new int[]{1, 1, 1, 2, 2, 3}, 2);
		new Leet347().topKFrequent(new int[]{4,1,-1,2,-1,2,3}, 2);
	}

	/**
	 * 我:先HashMap再TreeMap,非常接近正确答案,但TreeMap的key不能重复导致还是有bug
	 * 看别人后改良TreeMap<Integer,List>
	 * 54%,92%
	 */
	public int[] topKFrequent(int[] nums, int k) {
		if (nums == null || nums.length < 2 || k >= nums.length) return nums;

		HashMap<Integer,Integer> map=new HashMap();
		for (int num : nums) {
			if(map.containsKey(num))map.put(num,map.get(num)+1);
			else map.put(num,1);
		}
		TreeMap<Integer,List<Integer>> tree=new TreeMap();
		for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
			Integer count = entry.getValue();
			Integer num = entry.getKey();
			ArrayList<Integer> integers;
			if (tree.get(count)==null) {
				integers = new ArrayList<>();
				integers.add(num);
				tree.put(count, integers);
			} else {
				tree.get(count).add(num);
			}
		}
		int[] res=new int[k];
		int count=0;
		h:
		for (Map.Entry<Integer, List<Integer>> descMap : tree.descendingMap().entrySet()) {
			List<Integer> value = descMap.getValue();
			while (value.size()!=0){
				Integer remove = value.remove(0);
				res[count++]=remove;
				if(count==k)break h;
			}
		}
		return res;
	}
}
